package com.attendance.www.hr.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Service;

import com.attendance.www.hr.beans.ClosedBean;
import com.attendance.www.hr.beans.ClosedDayBean;
import com.attendance.www.hr.beans.ClosedPageBean;
import com.attendance.www.hr.dao.mapper.ApprovalRecordMapper;
import com.attendance.www.hr.dao.mapper.AttendanceMapper;
import com.attendance.www.hr.dao.mapper.ClosedDayMapper;
import com.attendance.www.hr.dao.mapper.ClosedExtMapper;
import com.attendance.www.hr.dao.mapper.ClosedMapper;
import com.attendance.www.hr.dao.mapper.RequestMapper;
import com.attendance.www.hr.dao.mapper.RetroactiveMapper;
import com.attendance.www.hr.entitys.ApprovalRecord;
import com.attendance.www.hr.entitys.ApprovalRecordExample;
import com.attendance.www.hr.entitys.Attendance;
import com.attendance.www.hr.entitys.AttendanceExample;
import com.attendance.www.hr.entitys.Closed;
import com.attendance.www.hr.entitys.ClosedDay;
import com.attendance.www.hr.entitys.ClosedDayExample;
import com.attendance.www.hr.entitys.ClosedExample;
import com.attendance.www.hr.entitys.ClosedExample.Criteria;
import com.attendance.www.hr.entitys.Request;
import com.attendance.www.hr.entitys.RequestExample;
import com.attendance.www.hr.entitys.Retroactive;
import com.attendance.www.hr.entitys.RetroactiveExample;
import com.attendance.www.hr.exception.ResultFaultException;
import com.attendance.www.hr.service.IClosedService;

@Service
public class ClosedServiceImpl implements IClosedService {

	@Resource
	private ClosedMapper closedDao;
	@Resource
	private ClosedExtMapper closedExtDao;
	@Resource
	private ApprovalRecordMapper approvalRecordDao;
	@Resource
	private RequestMapper requestDao;
	@Resource
	private RetroactiveMapper retroactiveDao;
	@Resource
	private AttendanceMapper attendanceDao;
	@Resource
	private ClosedDayMapper closedDayDao;

	/**
	 * 查询封账设置
	 * 
	 * @return
	 */
	@Override
	public ClosedPageBean getClosedPageList(ClosedBean closedBean,Integer startNum, Integer pageCount) {
		ClosedPageBean closedPageBean = new ClosedPageBean();
		closedPageBean.setClosedBeanList(closedExtDao.getClosedPageList(closedBean,startNum, pageCount));
		closedPageBean.setPageTotal(closedExtDao.getClosedCount(closedBean));
		return closedPageBean;
	}

	/**
	 * 根据ID获取封账信息
	 * 
	 * @param closedId
	 * @return
	 */
	public ClosedBean getClosedById(Integer closedId) {
		// 获取封账
		ClosedBean closedBean = new ClosedBean();
		Closed closed = closedDao.selectByPrimaryKey(closedId);
		if (closed != null) {
			closedBean.setClosedId(closedId);
			closedBean.setClosedYear(closed.getClosedYear());
			closedBean.setClosedMonth(closed.getClosedMonth());
		}
		// 获取封账天明细
		ClosedDayExample closedDayExample = new ClosedDayExample();
		closedDayExample.createCriteria().andClosedIdEqualTo(closedId);
		List<ClosedDay> closedDayList = closedDayDao.selectByExample(closedDayExample);
		List<ClosedDayBean> closedDayBeanList = new ArrayList<ClosedDayBean>();
		for (int i = 0; i < closedDayList.size(); i++) {
			ClosedDayBean closedDayBean = new ClosedDayBean();
			closedDayBean.setCheckbox(true);
			closedDayBean.setClosedDayDate(closedDayList.get(i).getClosedDayDate());
			closedDayBeanList.add(closedDayBean);
		}
		closedBean.setClosedDayList(closedDayBeanList);
		return closedBean;
	}

	/**
	 * 验证封账是否存在
	 * 
	 * @param closedBean
	 * @return
	 */
	@Override
	public boolean closedVerify(ClosedBean closedBean) {
		ClosedExample example = new ClosedExample();
		Criteria criteria = example.createCriteria();
		criteria.andClosedYearEqualTo(closedBean.getClosedYear());
		criteria.andClosedMonthEqualTo(closedBean.getClosedMonth());
		if (closedBean.getClosedId() != null) {
			criteria.andClosedIdNotEqualTo(closedBean.getClosedId());
		}
		List<Closed> closedList = closedDao.selectByExample(example);
		if (closedList.size() > 0) {
			return true;
		}
		return false;
	}

	/**
	 * 新增封账时间
	 */
	@Override
	public boolean saveClosed(ClosedBean closedBean) {
		// 主表封账保存
		Closed closed = new Closed();
		closed.setClosedYear(closedBean.getClosedYear());
		closed.setClosedMonth(closedBean.getClosedMonth());
		int record = closedDao.insertSelective(closed);
		if (record <= 0) {
			return false;
		}
		
		// 从表封账日期保存
		for (int i = 0; i < closedBean.getClosedDayList().size(); i++) {
			ClosedDayBean closedDayBean = closedBean.getClosedDayList().get(i);
			if(closedDayBean.isCheckbox()) {
				ClosedDay closedDay = new ClosedDay();
				closedDay.setClosedId(closed.getClosedId());
				closedDay.setClosedDayDate(closedDayBean.getClosedDayDate());
				closedDayDao.insertSelective(closedDay);
			}
		}
		
		// 查询封账日期
		ClosedDayExample closedDayExample=new ClosedDayExample();
		closedDayExample.createCriteria().andClosedIdEqualTo(closed.getClosedId());
		List<ClosedDay> closedDayList=closedDayDao.selectByExample(closedDayExample);
		List<Date> dayList=closedDayList.stream().map(ClosedDay::getClosedDayDate).collect(Collectors.toList());
		// 更新封账时间段内的待审批(1)记录，状态改为4，“已封账”(1改成4)
		this.updateApprovalRecord(1, 4,null,null,dayList);
		this.updateApprovalRecord(4, 1,closed.getClosedYear(),closed.getClosedMonth(),dayList);
		return true;
	}

	/**
	 * 修改封账
	 * 
	 * @param closedBean
	 * @return
	 */
	@Override
	public boolean updateClosed(ClosedBean closedBean) {
		// 主表封账保存
		Closed closed = new Closed();
		closed.setClosedId(closedBean.getClosedId());
		closed.setClosedYear(closedBean.getClosedYear());
		closed.setClosedMonth(closedBean.getClosedMonth());
		int record = closedDao.updateByPrimaryKeySelective(closed);
		if (record <= 0) {
			return false;
		}
		
		// 先删除,后添加
		ClosedDayExample closedDayExample = new ClosedDayExample();
		closedDayExample.createCriteria().andClosedIdEqualTo(closedBean.getClosedId());
		closedDayDao.deleteByExample(closedDayExample);
		
		// 从表封账日期保存
		for (int i = 0; i < closedBean.getClosedDayList().size(); i++) {
			ClosedDayBean closedDayBean = closedBean.getClosedDayList().get(i);
			if(closedDayBean.isCheckbox()) {
				ClosedDay closedDay = new ClosedDay();
				closedDay.setClosedId(closed.getClosedId());
				closedDay.setClosedDayDate(closedDayBean.getClosedDayDate());
				closedDayDao.insertSelective(closedDay);
			}
		}
		
		// 查询封账日期
		closedDayExample=new ClosedDayExample();
		closedDayExample.createCriteria().andClosedIdEqualTo(closed.getClosedId());
		List<ClosedDay> closedDayList=closedDayDao.selectByExample(closedDayExample);
		List<Date> dayList=closedDayList.stream().map(ClosedDay::getClosedDayDate).collect(Collectors.toList());
		// 更新封账时间段内的待审批(1)记录，状态改为4，“已封账”(1改成4)
		this.updateApprovalRecord(1, 4,null,null,dayList);
		this.updateApprovalRecord(4, 1,closed.getClosedYear(),closed.getClosedMonth(),dayList);
		return true;
	}

	/**
	 * 删除封帐时间
	 */
	@Override
	public boolean deleteClosed(Integer closedId) {
		// 查询是否被删除
		Closed closed = closedDao.selectByPrimaryKey(closedId);
		if (closed == null) {
			throw new ResultFaultException("0_00012");
		}
		// 删除主表封账
		int record = closedDao.deleteByPrimaryKey(closedId);
		if (record <= 0) {
			return false;
		}
		
		// 查询封账日期
		ClosedDayExample closedDayExample=new ClosedDayExample();
		closedDayExample.createCriteria().andClosedIdEqualTo(closedId);
		List<ClosedDay> closedDayList=closedDayDao.selectByExample(closedDayExample);
		List<Date> dayList=closedDayList.stream().map(ClosedDay::getClosedDayDate).collect(Collectors.toList());
		
		// //删除从表日期
		closedDayExample = new ClosedDayExample();
		closedDayExample.createCriteria().andClosedIdEqualTo(closedId);
		closedDayDao.deleteByExample(closedDayExample);
		
		// 解封时，更新封账时间段内的已封账(4)的记录，状态改为1，“待审批”（4改成1）
		this.updateApprovalRecord(4, 1,closed.getClosedYear(),closed.getClosedMonth(),dayList);
		return true;
	}

	/**
	 * 新增或删除封账时，更新审批记录
	 * @param year
	 * @param month
	 * @param isApprove
	 *            初始审批记录的状态
	 * @param isApproveTo
	 *            改成的审批记录的状态
	 */
	private void updateApprovalRecord(Integer isApprove, Integer isApproveTo,Integer year,Integer month,List<Date> dayList) {
		// 审批记录idList
		List<Integer> requestIdList = closedExtDao.getRequestIdByClosed(isApprove,year,month,dayList);
		List<Integer> retroactiveIdList = closedExtDao.getRetroactiveIdByClosed(isApprove,year,month,dayList);
		// 考勤记录
		List<Integer> attendanceIdList = closedExtDao.getAttendanceIdByClosed(isApprove,year,month,dayList);
		if (requestIdList.size() > 0) {// 有记录
			// 更新审批记录，更新申请记录
			ApprovalRecordExample arExample = new ApprovalRecordExample();
			arExample.createCriteria().andRequestIdIn(requestIdList);
			ApprovalRecord ar = new ApprovalRecord();
			ar.setIsApprove(isApproveTo);
			approvalRecordDao.updateByExampleSelective(ar, arExample);

			// 更新申请
			RequestExample rExample = new RequestExample();
			rExample.createCriteria().andRequestIdIn(requestIdList);
			Request request = new Request();
			request.setApprovalState(isApproveTo);
			requestDao.updateByExampleSelective(request, rExample);
		}
		if (retroactiveIdList.size() > 0) {
			// 更新审批记录，更新申请记录
			ApprovalRecordExample arExample = new ApprovalRecordExample();
			arExample.createCriteria().andRetroactiveIdIn(retroactiveIdList);
			ApprovalRecord ar = new ApprovalRecord();
			ar.setIsApprove(isApproveTo);
			approvalRecordDao.updateByExampleSelective(ar, arExample);

			// 更新补签
			RetroactiveExample rExample = new RetroactiveExample();
			rExample.createCriteria().andRetroactiveIdIn(retroactiveIdList);
			Retroactive retroactive = new Retroactive();
			retroactive.setApprovalState(isApproveTo);
			retroactiveDao.updateByExampleSelective(retroactive, rExample);
		}
		// 更新考勤记录
		if (attendanceIdList.size() > 0) {
			AttendanceExample attendanceExample = new AttendanceExample();
			attendanceExample.createCriteria().andAttendanceIdIn(attendanceIdList);
			Attendance att = new Attendance();
			att.setIsRepaired(isApproveTo);
			att.setIsApprovaled(isApproveTo);
			attendanceDao.updateByExampleSelective(att, attendanceExample);
		}
	}

	/**
	 * 封账验证 true 已封账
	 */
	@Override
	public boolean verifyClosed(Integer year, Integer month) {
		// 查询封账的年，月
		ClosedExample closedExample = new ClosedExample();
		closedExample.createCriteria().andClosedYearEqualTo(year).andClosedMonthEqualTo(month);
		List<Closed> closedList = closedDao.selectByExample(closedExample);
		if (closedList.size() > 0) {
			return true;
		} else {
			return false;
		}
	}
}
